package bluejack.game.engine;
import bluejack.operation.Oper;
import minimalcomps.PushButton;
import nme.display.DisplayObjectContainer;
import nme.display.Sprite;
import nme.events.Event;
import nme.events.EventDispatcher;
import nme.Lib;
import nme.utils.Timer;

/**
 * ...
 * @author BlueJack
 */

class GE 
{
	static public var curScene:Scene;
	static public var scriptManager(get_scriptManager, null):ScriptManager;
	static public var eventDispatcher(get_eventDispatcher, null):EventDispatcher;
	static public var mainSprite(get_mainSprite, null):Sprite;
	
	public static function startup(p_mainSprite:Sprite):Void {
		_eventDispatcher = new EventDispatcher();
		_scriptManager = ScriptManager.getInstance();
		_sceneList = new Hash<Scene>();
		_mainSprite = p_mainSprite;
		//_timer = new Timer(25);
		//_timer.addEventListener(TimerEvent.TIMER, onTimer);
	}
	
	public static function addScene(p_scene:Scene):Void {
		_sceneList.set(p_scene.name, p_scene);
	}
	
	public static function swapScene(p_name:String):Void {
		var nxtScene:Scene = _sceneList.get(p_name);
		if (nxtScene == null) return;
		if (curScene != null) new ExitSceneOper(curScene).commit();
		new EnterSceneOper(nxtScene).commit();
	}
	
	public static function createSprite(p_parent:DisplayObjectContainer = null):Sprite {
		var spri:Sprite = new Sprite();
		if (p_parent == null) p_parent = curScene;
		p_parent.addChild(spri);
		return spri;
	}
	
	public static function createButton(?parent:Dynamic = null, ?xpos:Float = 0, ?ypos:Float =  0, ?label:String = ""):PushButton {
		return new PushButton(parent, xpos, ypos, label);
	}
	
	//static private function onTimer(e:TimerEvent):Void {
		//if (curScene == null) return;
		//curScene.onTick();
	//}

	static private var _mainSprite:Sprite;
	static private var _timer:Timer;
	//static private var _curScene:Scene;
	static private var _sceneList:Hash<Scene>;
	static private var _scriptManager:ScriptManager;
	static private var _eventDispatcher:EventDispatcher;
	
	//static private function get_curScene():Scene {
		//return _curScene;
	//}
	
	static private function get_scriptManager():ScriptManager {
		return _scriptManager;
	}
	
	static private function get_eventDispatcher():EventDispatcher {
		return _eventDispatcher;
	}
	
	static private function get_mainSprite():Sprite {
		return _mainSprite;
	}
	
}

class ExitSceneOper extends Oper
{
	public var scene:Scene;

	public function new(scene:Scene) {
		this.scene = scene;
		super();
	}
	
	override public function execute():Void {
		scene.addEventListener(Event.REMOVED_FROM_STAGE, result);
		scene.onExit();
		GE.mainSprite.removeChild(scene);
		super.execute();
	}
	override public function result(event:Dynamic = null):Void {
		scene.removeEventListener(Event.REMOVED_FROM_STAGE, result);
		GE.curScene = null;
		super.result(event);
	}
}

class EnterSceneOper extends Oper
{
	public var scene:Scene;

	public function new(scene:Scene) {
		this.scene = scene;
		super();
	}
	
	override public function execute():Void {
		scene.addEventListener(Event.ADDED_TO_STAGE, result);
		GE.mainSprite.addChild(scene);
		super.execute();
	}
	
	override public function result(event:Dynamic = null):Void {
		scene.removeEventListener(Event.ADDED_TO_STAGE, result);
		scene.onEnter();
		GE.curScene = scene;
		super.result(event);
	}
}